import { Animation, Collider2D, Component, Contact2DType, IPhysics2DContact, Size, Sprite, UITransform, Vec2 } from 'cc';
import { MaxWidth } from '../../consts';
import Utils from '../../utils';

export abstract class AbstractEntity extends Component {
    private id: number;
    protected roleName: string = '';
    public getID() {
        return this.id;
    }

    protected isInit: boolean = false;
    public abstract init(name: string): void; // 初始化时调用，onLoad之后
    protected abstract destructor(): void; // 析构函数，onDestroy调用

    protected size: Size;
    protected sprite: Sprite;
    protected isEndGame: boolean = false;
    protected colliderBody: Collider2D; // 碰撞范围
    protected anima: Animation = null; // 动画组件
    protected onLoad(): void {
        this.id = Utils.tools.genUUID();
        this.size = this.node.getComponent(UITransform).contentSize;
        this.sprite = this.node.getComponent(Sprite);
        this.anima = this.node.getComponent(Animation);
        this.colliderBody = this.node.getComponent(Collider2D);
        this.colliderBody.on(Contact2DType.BEGIN_CONTACT, this.onPhysicsCollision, this);
    }
    protected onDestroy(): void {
        this.colliderBody.off(Contact2DType.BEGIN_CONTACT, this.onPhysicsCollision, this);
        this.destructor();
    }

    // body碰撞
    protected abstract onPhysicsCollision(selfCollider: Collider2D, otherCollider: Collider2D, contact: IPhysics2DContact | null): void;

    protected isJoinTheWorld: boolean;
    public abstract joinTheWorld(): void;
    public abstract exitTheWorld(): void; // 强行退出世界
}

export class RoleAnimation {
    private name: string;
    private isInit: boolean = false;
    init(name: string) {
        if (this.isInit) return;
        this.name = name;
        this.isInit = true;
    }
    public playAnimation(anima: Animation, name: string): void {
        if (!this.isInit) return;
        anima.play(name);
    }
    public hit(anima: Animation): void {
        this.playAnimation(anima, 'hit' + this.name);
    }
    public idle(anima: Animation): void {
        this.playAnimation(anima, 'idle' + this.name);
    }
    public dead(anima: Animation): void {
        this.playAnimation(anima, 'down' + this.name);
    }
}

// 角色血量
export class HpProperty {
    private hp = 0;
    public init(hp: number) {
        this.hp = hp;
    }
    public add(hp: number): void {
        this.hp += hp;
    }
    public sub(hp: number): void {
        this.hp -= hp;
    }
    public getScore(): number {
        return this.hp;
    }
    public isDead(): boolean {
        return this.hp <= 0;
    }
}

// 玩家得分
export class ScoreProperty {
    private score = 0; // 分数
    public clearScore() {
        this.score = 0;
    }
    public addScore(score: number) {
        this.score += score;
    }
    public getScore(): number {
        return this.score;
    }
}

export const generatePos = (size: Size): Vec2 => {
    const winSize = Utils.sys.getPlatform().windowSize;
    const x = (Math.random() - 0.5) * (MaxWidth - size.width);
    const y = (winSize.height + size.height) / 2;
    return new Vec2(x, y);
};
